package com.hc.smartcall;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Test;

import java.security.SecureRandom;
import java.security.Security;
import java.util.Random;

public class SM2EncryptionExample {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    @Test
    public void testSm2() throws Exception {
        // 生成密钥对
        AsymmetricCipherKeyPair keyPair = generateKeyPair();
        ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
        ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();

        // 待加密的明文
        String plainText = "Hello, SM2!";
        byte[] plainBytes = plainText.getBytes();

        // 加密
        byte[] encryptedBytes = encrypt(publicKey, plainBytes);
        System.out.println("Encrypted: " + Hex.toHexString(encryptedBytes));

        // 解密
        byte[] decryptedBytes = decrypt(privateKey, encryptedBytes);
        System.out.println("Decrypted: " + new String(decryptedBytes));
    }

    public static AsymmetricCipherKeyPair generateKeyPair() {
        X9ECParameters ecParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(
                ecParameters.getCurve(),
                ecParameters.getG(),
                ecParameters.getN(),
                ecParameters.getH()
        );
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(
                domainParameters,
                new SecureRandom()
        );
        keyPairGenerator.init(keyGenerationParameters);
        return keyPairGenerator.generateKeyPair();
    }

    public static byte[] encrypt(ECPublicKeyParameters publicKey, byte[] plainBytes) throws Exception {
        SM2Engine engine = new SM2Engine();
        engine.init(true, new ParametersWithRandom(publicKey, new SecureRandom()));
        return engine.processBlock(plainBytes, 0, plainBytes.length);
    }

    public static byte[] decrypt(ECPrivateKeyParameters privateKey, byte[] encryptedBytes) throws Exception {
        SM2Engine engine = new SM2Engine();
        engine.init(false, privateKey);
        return engine.processBlock(encryptedBytes, 0, encryptedBytes.length);
    }
}    